昨天介紹了 NetworkPolicy 的使用方式,但 kind 預設的 CNI 不支援 NetworkPolicy,所以今天我們將來安裝 Cilium 作為 CNI,並透過 Hubble 的 Service Map 來觀察 NetworkPolicy 的行為和網路流量。
代碼能參閱 GitHub
調整 kind-config.yml 禁用預設 CNI
apiVersion: kind.x-k8s.io/v1alpha4
kind: Cluster
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30000
hostPort: 30000
listenAddress: "0.0.0.0" # Optional, defaults to "0.0.0.0"
protocol: tcp # Optional, defaults to tcp
- containerPort: 30001
hostPort: 30001
listenAddress: "0.0.0.0" # Optional, defaults to "0.0.0.0"
protocol: tcp # Optional, defaults to tcp
- role: worker
labels:
zone: local-a
- role: worker
labels:
zone: local-a
GPU: "true"
- role: worker
labels:
zone: local-b
- role: worker
labels:
zone: local-b
networking:
disableDefaultCNI: true
建立 cluster
kind create cluster --config=kind-config.yaml
# Setup Helm repository:
helm repo add cilium https://helm.cilium.io/
# Preload the cilium image into each worker node in the kind cluster:
docker pull quay.io/cilium/cilium:v1.16.1
kind load docker-image quay.io/cilium/cilium:v1.16.1
# Then, install Cilium release via Helm:
helm install cilium cilium/cilium --version 1.16.1 \
--namespace kube-system \
--set image.pullPolicy=IfNotPresent \
--set ipam.mode=kubernetes
安裝 cilium CLI ,用來驗證 CNI 配置是否成功
# Install cilium in MacOsS
CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
CLI_ARCH=amd64
if [ "$(uname -m)" = "arm64" ]; then CLI_ARCH=arm64; fi
curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-darwin-${CLI_ARCH}.tar.gz{,.sha256sum}
shasum -a 256 -c cilium-darwin-${CLI_ARCH}.tar.gz.sha256sum
sudo tar xzvfC cilium-darwin-${CLI_ARCH}.tar.gz /usr/local/bin
rm cilium-darwin-${CLI_ARCH}.tar.gz{,.sha256sum}
驗證 cilium 是否正常運作在 kind 建立的 k8s
cilium status --wait
看到以下畫面,能看到 Cilium
、Operator
、Envoy DaemonSet
狀態為 OK 即代表成功將 Cilium
安裝到 k8s 中。
/¯¯\
/¯¯\__/¯¯\ Cilium: OK
\__/¯¯\__/ Operator: OK
/¯¯\__/¯¯\ Envoy DaemonSet: OK
\__/¯¯\__/ Hubble Relay: disabled
\__/ ClusterMesh: disabled
# ... 以下省略
接著我們來啟用 Hubble 與 Hubble Web UI,後續要用來觀察網路流量時使用
helm upgrade cilium cilium/cilium --version 1.16.1 \
--namespace kube-system \
--reuse-values \
--set hubble.relay.enabled=true \
--set hubble.ui.enabled=true
再次透過 cilium status
指令,檢查 Hubble Relay
狀態應轉為 OK
/¯¯\
/¯¯\__/¯¯\ Cilium: OK
\__/¯¯\__/ Operator: OK
/¯¯\__/¯¯\ Envoy DaemonSet: OK
\__/¯¯\__/ Hubble Relay: OK
\__/ ClusterMesh: disabled
將部署三個 deployment,分別當作 three-tier 架構的每一層的其中一個服務
# 建立 namespace
kubectl create namespace ithome
# 切換 context namespace 到 ithome,之後執行 kubectl 會自帶 -n ithome
kubens ithome
# Install the deployment/Pod with tier=frontend
kubectl apply -f https://raw.githubusercontent.com/YihongGao/iThome_30Day_2024/main/resources/day15/workload/frontend.yml
# Install the deployment/Pod with tier=backend
kubectl apply -f https://raw.githubusercontent.com/YihongGao/iThome_30Day_2024/main/resources/day15/workload/backend.yml
# Install the deployment/Pod with tier=data
kubectl apply -f https://raw.githubusercontent.com/YihongGao/iThome_30Day_2024/main/resources/day15/workload/db.yml
再開始配置 NetworkPolicy 之前,我們先開啟 hubble 的 Service Map 功能觀察 Pod 之間的網路流量。
cilium hubble ui
能在本地瀏覽器中開啟 Web UI,並選到 ithome 的 namespace
目前 UI 上還沒任何流量資訊,讓我們打一些流量到 frontend Pod
kubectl exec -it ${you frontend pod name} -- curl localhost:80
# Response
{
"message": "Hello from ithome demo data!"
}
再能看到 UI 上流量如何在 Pod 之間行進的,而下方也有抓取流量封包的詳細資訊
先配置拒絕全部進出流量的 NetworkPolicy 並向 frontend 打一個 Http request
kubectl apply https://raw.githubusercontent.com/YihongGao/iThome_30Day_2024/main/resources/day15/network-policy/default-deny-all.yml
kubectl exec -it ${you frontend pod name} -- curl localhost:80
等待一陣子後,Response 會出現 504 Gateway Time-out,代表 frontend Pod 連不上 backend Pod
<html>
<head><title>504 Gateway Time-out</title></head>
<body>
<center><h1>504 Gateway Time-out</h1></center>
<hr><center>nginx/1.27.1</center>
</body>
</html>
Hubble UI 也會展示哪一段網路連線失敗
以上符合我們的預期,因爲目前只配置了拒絕全部進出流量的 NetworkPolicy 到所有 Pod 上,接下來我們要逐步開放 Pod 之間的連線
# frontend-tier-policy
kubectl apply -f https://raw.githubusercontent.com/YihongGao/iThome_30Day_2024/main/resources/day15/network-policy/frontend-tier-policy.yml
# backend-tier-policy
kubectl apply -f https://raw.githubusercontent.com/YihongGao/iThome_30Day_2024/main/resources/day15/network-policy/backend-tier-policy.yml
kubectl exec -it ${you frontend pod name} -- curl localhost:80
我們會發現一樣回應 504 Gateway Time-out,但能從 Hubble UI 發現是 backend 向 db 發出 http 連線時被阻擋了。
kubectl apply -f https://raw.githubusercontent.com/YihongGao/iThome_30Day_2024/main/resources/day15/network-policy/data-tier-policy.yml
kubectl exec -it ${you frontend pod name} -- curl localhost:80
# Response
{
"message": "Hello from ithome demo data!"
}
這次能看到請求成功了,並且能在 Hubble UI 看到 backend 到 db 之間的連線打通了。
今天介紹了如何在 kind 環境中安裝並配置 Cilium 作為 CNI,並啟用 Hubble 來觀察 Kubernetes 中的網路流量。透過配置不同的 NetworkPolicy,我們展示了如何使用三層架構的 Pod(Frontend、Backend、DB)進行流量控制,並通過 Hubble 的可視化介面驗證網路連接的行為。
明天將進入 CI/CD pipeline 的實作,屆時我們會使用 Kustomize 和 ArgoCD,對去年的陽春版 pipeline 進行迭代,打造一個更易於維護的 CI/CD 流程。